﻿Imports System
Imports System.Collections
Imports System.IO
Imports System.Xml
Imports System.Xml.Serialization
Imports ICSharpCode.SharpZipLib.Zip
Imports unRar
Imports System.ComponentModel

Public Class comic
    Implements INotifyPropertyChanged


    Public Sub New(ByVal fileName As String)
        LoadFile(fileName)
        ' TODO  : Do Comic Info Load Here "
        IsDirty = False
    End Sub


    Private path As String
    Private TempFolder As String
    Private _fileList As New List(Of String)
    Private actualIndex As Integer = -1
    Private disposedValue As Boolean = False        ' To detect redundant calls
    Private readMePath As String = String.Empty

    Private Sub ClearValues()
        Me.titleField = ""
        Me.seriesField = ""
        Me.numberField = ""
        Me.countField = -1
        Me.volumeField = -1
        Me.alternateSeriesField = ""
        Me.alternateNumberField = ""
        Me.alternateCountField = -1
        Me.summaryField = ""
        Me.notesField = ""
        Me.yearField = -1
        Me.monthField = -1
        Me.writerField = ""
        Me.pencillerField = ""
        Me.inkerField = ""
        Me.coloristField = ""
        Me.lettererField = ""
        Me.coverArtistField = ""
        Me.editorField = ""
        Me.publisherField = ""
        Me.imprintField = ""
        Me.genreField = ""
        Me.webField = ""
        Me.pageCountField = 0
        Me.languageISOField = ""
        Me.formatField = ""
        Me.blackAndWhiteField = YesNo.Unknown
        Me.mangaField = YesNo.Unknown
        Me._pages = New ComicPages
    End Sub

    Public Sub LoadFile(ByVal fileName As String)
        ClearValues()
        If IO.File.Exists(fileName) Then

            Me.path = fileName
            Dim str As String = My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData
            Dim xfileName As String = IO.Path.GetFileNameWithoutExtension(Me.path)
            Dim ext As String = IO.Path.GetExtension(Me.path)
            TempFolder = str & "/editor/archives/" & xfileName
            ext = Replace(ext, ".", "")
            Select Case ext
                Case "cbz", "gzip", "zip"
                    unZip()
                Case "rar", "cbr"
                    unrar()
                Case Else
                    Throw New NotImplementedException(String.Format("Using {0} has not been implemented yet.", ext))
            End Select
            LoadFileNames()
        ElseIf IO.Directory.Exists(fileName) Then
        Else
            Throw New FileNotFoundException()
        End If
    End Sub

    Private Sub LoadFileNames()
        Dim fileList As New List(Of String)
        LoadFilesFromSubFolders(Me.TempFolder, fileList)
        fileList.Sort()
        For Each s As String In fileList
            Me.ComicPages.Add(New comicPage(s))
        Next
    End Sub

    Private Sub LoadFilesFromSubFolders(ByVal dirPath As String, ByRef fileList As List(Of String))
        For Each fn As String In Directory.GetFiles(dirPath)
            Dim ext As String = Replace(IO.Path.GetExtension(fn), ".", "")
            Select Case LCase(Trim(ext))
                Case "jpg", "jpeg", "gif", "bmp", "png"
                    fileList.Add(fn)
                Case "txt", "rtf"
                    readMePath = fn
                Case "xml"
                    'comicInfoFileName = fn
            End Select
        Next

        For Each dn As String In Directory.GetDirectories(dirPath)
            LoadFilesFromSubFolders(dn, fileList)
        Next ' Each dn As String In Directory.GetDirectories(dirPath) 
    End Sub ' LoadFilesFromSubFolders 

    Private Sub unrar()
        If Not IO.Directory.Exists(TempFolder) Then IO.Directory.CreateDirectory(TempFolder)
        Dim d As New Decompressor(Me.path)
        Dim b As Boolean = d.UnPackAll(Me.TempFolder)
        If Not b Then
            Throw New Exception("Rar Failed To Decompress")
        End If
    End Sub

    Private Sub unZip()
        If Not IO.Directory.Exists(TempFolder) Then IO.Directory.CreateDirectory(TempFolder)
        Dim s As New ZipInputStream(File.OpenRead(path))

        Dim theEntry As ZipEntry = s.GetNextEntry
        While Not theEntry Is Nothing
            Dim fileName As String = IO.Path.GetFileName(theEntry.Name)

            If Not fileName Is String.Empty AndAlso Not IO.File.Exists(TempFolder & "/" & fileName) Then
                Dim streamWriter As FileStream
                streamWriter = File.Create(TempFolder & "/" & fileName)
                Dim size As Integer = 2048
                Dim abyData(2048) As Byte
                While True
                    size = s.Read(abyData, 0, abyData.Length)
                    If size > 0 Then
                        streamWriter.Write(abyData, 0, size)
                    Else ' size > 0 
                        Exit While
                    End If ' size > 0 
                End While
                streamWriter.Flush()
                streamWriter.Close()
                streamWriter.Dispose()
            End If

            theEntry = s.GetNextEntry
        End While ' Not theEntry Is Nothing 		
    End Sub


    Public Sub AddComicPage(ByVal item As comicPage)
        ' TODO : DO CHECKS HERE 
        Me.ComicPages.Add(item)
        OnPropertyChanged("ComicPages")
    End Sub

    Public ReadOnly Property ComicPages() As ComicPages
        Get
            If _pages Is Nothing Then _pages = New ComicPages
            Return _pages
        End Get
    End Property


#Region "Private Variables"
    Private _pages As New ComicPages
    Private titleField As String
    Private seriesField As String
    Private numberField As String
    Private countField As Integer
    Private volumeField As Integer
    Private alternateSeriesField As String
    Private alternateNumberField As String
    Private alternateCountField As Integer
    Private summaryField As String
    Private notesField As String
    Private yearField As Integer
    Private monthField As Integer
    Private writerField As String
    Private pencillerField As String
    Private inkerField As String
    Private coloristField As String
    Private lettererField As String
    Private coverArtistField As String
    Private editorField As String
    Private publisherField As String
    Private imprintField As String
    Private genreField As String
    Private webField As String
    Private pageCountField As Integer
    Private languageISOField As String
    Private formatField As String
    Private blackAndWhiteField As YesNo
    Private mangaField As YesNo
#End Region


    Public Sub New()
        MyBase.New()
        ClearValues()
    End Sub

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Title() As String
        Get
            Return Me.titleField
        End Get
        Set(ByVal value As String)
            Me.titleField = value
            OnPropertyChanged("Title")
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Series() As String
        Get
            Return Me.seriesField
        End Get
        Set(ByVal value As String)
            Me.seriesField = value
            OnPropertyChanged("Series")
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Number() As String
        Get
            Return Me.numberField
        End Get
        Set(ByVal value As String)
            Me.numberField = value
            OnPropertyChanged("Number")
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute(-1)> _
    Public Property Count() As Integer
        Get
            Return Me.countField
        End Get
        Set(ByVal value As Integer)
            Me.countField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute(-1)> _
    Public Property Volume() As Integer
        Get
            Return Me.volumeField
        End Get
        Set(ByVal value As Integer)
            Me.volumeField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property AlternateSeries() As String
        Get
            Return Me.alternateSeriesField
        End Get
        Set(ByVal value As String)
            Me.alternateSeriesField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property AlternateNumber() As String
        Get
            Return Me.alternateNumberField
        End Get
        Set(ByVal value As String)
            Me.alternateNumberField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute(-1)> _
    Public Property AlternateCount() As Integer
        Get
            Return Me.alternateCountField
        End Get
        Set(ByVal value As Integer)
            Me.alternateCountField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Summary() As String
        Get
            Return Me.summaryField
        End Get
        Set(ByVal value As String)
            Me.summaryField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Notes() As String
        Get
            Return Me.notesField
        End Get
        Set(ByVal value As String)
            Me.notesField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute(-1)> _
    Public Property Year() As Integer
        Get
            Return Me.yearField
        End Get
        Set(ByVal value As Integer)
            Me.yearField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute(-1)> _
    Public Property Month() As Integer
        Get
            Return Me.monthField
        End Get
        Set(ByVal value As Integer)
            Me.monthField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Writer() As String
        Get
            Return Me.writerField
        End Get
        Set(ByVal value As String)
            Me.writerField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Penciller() As String
        Get
            Return Me.pencillerField
        End Get
        Set(ByVal value As String)
            Me.pencillerField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Inker() As String
        Get
            Return Me.inkerField
        End Get
        Set(ByVal value As String)
            Me.inkerField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Colorist() As String
        Get
            Return Me.coloristField
        End Get
        Set(ByVal value As String)
            Me.coloristField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Letterer() As String
        Get
            Return Me.lettererField
        End Get
        Set(ByVal value As String)
            Me.lettererField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property CoverArtist() As String
        Get
            Return Me.coverArtistField
        End Get
        Set(ByVal value As String)
            Me.coverArtistField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Editor() As String
        Get
            Return Me.editorField
        End Get
        Set(ByVal value As String)
            Me.editorField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Publisher() As String
        Get
            Return Me.publisherField
        End Get
        Set(ByVal value As String)
            Me.publisherField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Imprint() As String
        Get
            Return Me.imprintField
        End Get
        Set(ByVal value As String)
            Me.imprintField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Genre() As String
        Get
            Return Me.genreField
        End Get
        Set(ByVal value As String)
            Me.genreField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Web() As String
        Get
            Return Me.webField
        End Get
        Set(ByVal value As String)
            Me.webField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute(0)> _
    Public Property PageCount() As Integer
        Get
            Return Me.pageCountField
        End Get
        Set(ByVal value As Integer)
            Me.pageCountField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property LanguageISO() As String
        Get
            Return Me.languageISOField
        End Get
        Set(ByVal value As String)
            Me.languageISOField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute("")> _
    Public Property Format() As String
        Get
            Return Me.formatField
        End Get
        Set(ByVal value As String)
            Me.formatField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute(YesNo.Unknown)> _
    Public Property BlackAndWhite() As YesNo
        Get
            Return Me.blackAndWhiteField
        End Get
        Set(ByVal value As YesNo)
            Me.blackAndWhiteField = value
        End Set
    End Property

    '''<remarks/>
    <System.ComponentModel.DefaultValueAttribute(YesNo.Unknown)> _
    Public Property Manga() As YesNo
        Get
            Return Me.mangaField
        End Get
        Set(ByVal value As YesNo)
            Me.mangaField = value
        End Set
    End Property


    Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
        Me.IsDirty = True
    End Sub

    Private _isDirty As Boolean = False
    Public Property IsDirty() As Boolean
        Get
            Return _isDirty
        End Get
        Private Set(ByVal value As Boolean)
            _isDirty = value
        End Set
    End Property


    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

End Class
